//! Validation models
//! 
//! This module defines validation-related structures for test assertions.

use crate::models::Value;
use serde::{Deserialize, Serialize};

/// Validator configuration
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Validator {
    /// Validator type
    pub validator_type: ValidatorType,
    
    /// Expected value
    pub expected: Option<Value>,
    
    /// JSONPath or XPath expression
    pub expression: Option<String>,
    
    /// Error message template
    pub message: Option<String>,
}

/// Validator types
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ValidatorType {
    /// Equality check
    Equals,
    
    /// Contains check
    Contains,
    
    /// Regular expression match
    Regex,
    
    /// JSONPath validation
    JsonPath,
    
    /// XPath validation
    XPath,
    
    /// Status code validation
    StatusCode,
    
    /// Header validation
    Header,
    
    /// Response time validation
    ResponseTime,
    
    /// Custom validator
    Custom(String),
}

/// Validation result
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ValidationResult {
    /// Validator name
    pub validator: String,
    
    /// Whether validation passed
    pub passed: bool,
    
    /// Expected value
    pub expected: Option<Value>,
    
    /// Actual value
    pub actual: Option<Value>,
    
    /// Error message
    pub error: Option<String>,
}

impl Validator {
    /// Create an equality validator
    pub fn equals(expected: Value) -> Self {
        Self {
            validator_type: ValidatorType::Equals,
            expected: Some(expected),
            expression: None,
            message: None,
        }
    }
    
    /// Create a contains validator
    pub fn contains(expected: Value) -> Self {
        Self {
            validator_type: ValidatorType::Contains,
            expected: Some(expected),
            expression: None,
            message: None,
        }
    }
    
    /// Create a status code validator
    pub fn status_code(expected: u16) -> Self {
        Self {
            validator_type: ValidatorType::StatusCode,
            expected: Some(Value::Number(expected.into())),
            expression: None,
            message: None,
        }
    }
    
    /// Create a JSONPath validator
    pub fn json_path(expression: String, expected: Value) -> Self {
        Self {
            validator_type: ValidatorType::JsonPath,
            expected: Some(expected),
            expression: Some(expression),
            message: None,
        }
    }
}

impl ValidationResult {
    /// Create a successful validation result
    pub fn success(validator: String, expected: Option<Value>, actual: Option<Value>) -> Self {
        Self {
            validator,
            passed: true,
            expected,
            actual,
            error: None,
        }
    }
    
    /// Create a failed validation result
    pub fn failure(validator: String, expected: Option<Value>, actual: Option<Value>, error: String) -> Self {
        Self {
            validator,
            passed: false,
            expected,
            actual,
            error: Some(error),
        }
    }
}
